import java.io.*;
import java.net.*;

class FileHeader implements Serializable
{
	public boolean isFile = false;
	public boolean canRead = false;
	public boolean canWrite = false;
	public boolean exists = false;
	public String name = "";
	public long	length = 0;
}

public class FileService
{
	public static final boolean BINARY = true;
	public static final boolean ASCII = false;		
	protected boolean mode = BINARY;
	protected File current = null;
								 
	public FileService()
	{
		current = new File(".");
	}
	
	public void setMode(boolean m)
	{
		mode = m;	
	}
	
	public String[] ls()
	{
		return current.list();
	}
	
	public boolean cd(String dir)
	{
		File newCurrent = new File(dir);
				
		if (!newCurrent.isAbsolute())
			newCurrent = new File(pwd(), dir);
		if (newCurrent.isDirectory())	
		{
			current = newCurrent;
			return true;
		}
		else
			return false;			
	}
	
	public String pwd()
	{
		try {
			return current.getCanonicalPath();
		}
		catch (Exception ex)
		{
			return null;
		}
	}
	
	public boolean mkdir(String dir)
	{
		File newDir = new File(dir);
		if (!newDir.isAbsolute())
			newDir = new File(pwd(), dir);
		return newDir.mkdirs();
	}
	
	public File getFileObject(String args)
	{
		return new File(pwd(), args);	
	}
	
	public FileHeader getFileHeader(File file)
	{
		FileHeader header = new FileHeader();
		
		header.isFile = file.isFile();
		header.canRead = file.canRead();
		header.canWrite = file.canWrite();
		header.exists = file.exists();
		header.name = file.getName();
		header.length = file.length();
		
		return header;
	}
	
	public void sendBinaryFile(File file, Socket skt)
	{
		BufferedInputStream bin = null;
		BufferedOutputStream bout = null;
		byte buf[] = new byte[2048];
		int read = 0;
				
		try
		{
			bout = new BufferedOutputStream(skt.getOutputStream());
			bin = new BufferedInputStream(new FileInputStream(file));
					
			while ((read = bin.read(buf)) > 0)
				bout.write(buf, 0, read);
			bout.flush();
			bin.close();
		} 
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public void sendAsciiFile(File file, Socket skt)
	{
		BufferedReader ain = null;
		BufferedWriter aout = null;
		String buf = null;
		
		try
		{
			aout = new BufferedWriter(new OutputStreamWriter(
					skt.getOutputStream()));
			ain = new BufferedReader(new FileReader(file));
			
			while ((buf = ain.readLine()) != null)
				aout.write(buf + "\n");
				
			aout.write("TRUE*****EOF*****TRUE" + "\n");
			aout.flush();
			ain.close();
		} 
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public void receiveBinaryFile(FileHeader header, Socket skt)
	{
		BufferedOutputStream bout = null;
		BufferedInputStream bin = null;
		byte buf[] = new byte[2048];
		int read = 0;
		long totalRead = 0;
		
		try
		{
			bout = new BufferedOutputStream(
				new FileOutputStream(getFileObject(header.name)));
			bin = new BufferedInputStream(skt.getInputStream());
			while (totalRead < header.length)
			{
				read = bin.read(buf);
				totalRead += read;
				bout.write(buf, 0, read);						
			}
			bout.close();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public void receiveAsciiFile(FileHeader header, Socket skt)
	{
		BufferedReader ain = null;
		BufferedWriter aout = null;
		String buf = null;
		
		try
		{
			aout = new BufferedWriter(
				new FileWriter(getFileObject(header.name)));
			ain = new BufferedReader(
				new InputStreamReader(skt.getInputStream()));
			
			while (!(buf = ain.readLine()).equals("TRUE*****EOF*****TRUE"))
			{
				aout.write(buf + "\n");
				aout.flush();
			}
			aout.close();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public File[] matches(String arg)
	{
		MyFilenameFilter filter = new MyFilenameFilter(current, arg);
		return current.listFiles(filter);
	}
}
